#include "Sphere.h"
#include <float.h>

Sphere::Sphere(Vec3f center, float radius, Material *pMaterial)
{
	m_center = center;
	m_radius = radius;
	m_pMaterial = pMaterial;
}

// suppose pRay.direction() .length==1
bool Sphere::intersect(const Ray *pRay, Hit *pHit, float tmin, float tmax)
{ 
	float a,b,c;
	a = 1.f;
	Vec3f temp = pRay->getOrigin()-m_center;
	b = 2 * pRay->getDirection().Dot3(temp);
	c = temp.Dot3(temp) - m_radius*m_radius;

	float delta = b*b - 4.f*a*c;
 	if ( delta > 0.f )
 	{
  		delta = sqrtf( delta );
 		float t1 = (-b - delta)/(2*a);
 		float t2 = (-b + delta)/(2*a);
 		if ( t1 > tmin && t1 < tmax )
 		{
			Vec3f n = pRay->getOrigin() + pRay->getDirection()*t1 - m_center;
			n /= m_radius;
			pHit->set(t1, m_pMaterial, n, *pRay);
			return true;	
 		}
		if ( t2 > tmin && t2 < tmax )
		{
			Vec3f n = pRay->getOrigin() + pRay->getDirection()*t2 - m_center;
			n /= m_radius;
			pHit->set(t2, m_pMaterial, n, *pRay);
			return true;
		}
 	}
	return false;
}

bool Sphere::intersectShadowRay(const Ray *pRay, float tmin, float tmax)
{
	float a,b,c;
	a = 1.f;
	Vec3f temp = pRay->getOrigin()-m_center;
	b = 2 * pRay->getDirection().Dot3(temp);
	c = temp.Dot3(temp) - m_radius*m_radius;

	float delta = b*b - 4.f*a*c;
	if ( delta > 0.f )
	{
		delta = sqrtf( delta );
		float t1 = (-b - delta)/(2*a);
		float t2 = (-b + delta)/(2*a);
		if ( t1 > tmin && t1 < tmax )
		{
			return true;	
		}
		if ( t2 > tmin && t2 < tmax )
		{
			return true;
		}
	}
	return false;
}